/*
 * objects.c
 *
 *  Created on: 2011-11-8
 *      Author: zhangtao
 */
#include <GL/gl.h>
#include <math.h>
#include "gl_objects.h"

#define PI 3.1415926f
#define JET_FACE_SIZE 17

void drawTorus(GLfloat majorRadius, GLfloat minorRadius, GLint numMajor, GLint numMinor){
	double majorStep = 2.0f * PI / numMajor;
	double minorStep = 2.0f * PI / numMinor;

	double a0 = 0;
	double a1 = majorStep;
	for(int i = 0; i < numMajor; i++){
		glBegin(GL_TRIANGLE_STRIP);
		double b = 0;
		for(int j = 0; j <= numMinor; j++){
			GLfloat c = (GLfloat)cos(b);
			GLfloat r = minorRadius * c + majorRadius;
			GLfloat z = minorRadius * (GLfloat)sin(b);
			glVertex3f(r * (GLfloat)cos(a0), r * (GLfloat)sin(a0), z);
			glVertex3f(r * (GLfloat)cos(a1), r * (GLfloat)sin(a1), z);
			b += minorStep;
		}
		glEnd();
		a0 = a1;
		a1 += majorStep;
	}
}
void drawMatrixLines(GLfloat xExtent, GLfloat zExtent, GLint linesNr){
	GLfloat xStep = xExtent / linesNr * 2;
	GLfloat zStep = zExtent / linesNr * 2;

	GLfloat z = -zExtent;
	GLfloat x = -xExtent;
	glBegin(GL_LINES);
	for(int i = 0; i <= linesNr; i++){
		glVertex3f(xExtent, 0, z);
		glVertex3f(-xExtent, 0, z);
		z += zStep;

		glVertex3f(x, 0, -zExtent);
		glVertex3f(x, 0, zExtent);
		x += xStep;
	}
	glEnd();
}
void drawGridPlane(GLfloat xExtent, GLfloat zExtent, GLint xLinesNr, GLint zLinesNr, GLubyte* color1, GLubyte* color2){
	GLfloat xStep = xExtent * 2 / xLinesNr;
	GLfloat zStep = zExtent * 2 / zLinesNr;

	GLfloat z0 = -zExtent;
	GLfloat z1 = z0 + zStep;

	GLboolean useColor1 = GL_TRUE;
	glNormal3f(0.0f, 1.0f, 0.0f);
	for(int i = 0; i < zLinesNr; i++){
		GLfloat x = -xExtent;
		glBegin(GL_QUAD_STRIP);
		for(int j = 0; j <= xLinesNr; j++){
			if(useColor1){
				glColor3ubv(color1);
				useColor1 = GL_FALSE;
			}else{
				glColor3ubv(color2);
				useColor1 = GL_TRUE;
			}
			glVertex3f(x, 0, z0);
			glVertex3f(x, 0, z1);
			x += xStep;
		}
		glEnd();
		z0 = z1;
		z1 += zStep;
	}
}
//vertexes data
static GLfloat vertexes[JET_FACE_SIZE * 9] = {
	// Nose Cone
	0.0f, 0.0f, 60.0f,
	-15.0f, 0.0f, 30.0f,
	15.0f,0.0f,30.0f,

	15.0f,0.0f,30.0f,
	0.0f, 15.0f, 30.0f,
	0.0f, 0.0f, 60.0f,

	0.0f, 0.0f, 60.0f,
	0.0f, 15.0f, 30.0f,
	-15.0f,0.0f,30.0f,

	-15.0f,0.0f,30.0f,
	0.0f, 15.0f, 30.0f,
	0.0f, 0.0f, -56.0f,

	0.0f, 0.0f, -56.0f,
	0.0f, 15.0f, 30.0f,
	15.0f,0.0f,30.0f,

	15.0f,0.0f,30.0f,
	-15.0f, 0.0f, 30.0f,
	0.0f, 0.0f, -56.0f,

	// Left wing
	// Large triangle for bottom of wing
	0.0f,2.0f,27.0f,
	-60.0f, 2.0f, -8.0f,
	60.0f, 2.0f, -8.0f,

	60.0f, 2.0f, -8.0f,
	0.0f, 7.0f, -8.0f,
	0.0f,2.0f,27.0f,

	60.0f, 2.0f, -8.0f,
	-60.0f, 2.0f, -8.0f,
	0.0f,7.0f,-8.0f,

	// Other wing top section
	0.0f,2.0f,27.0f,
	0.0f, 7.0f, -8.0f,
	-60.0f, 2.0f, -8.0f,

	// Tail section
	// Bottom of back fin
	-30.0f, -0.50f, -57.0f,
	30.0f, -0.50f, -57.0f,
	0.0f,-0.50f,-40.0f,

	//top of left side
	0.0f,-0.5f,-40.0f,
	30.0f, -0.5f, -57.0f,
	0.0f, 4.0f, -57.0f,

	//top of right side
	0.0f, 4.0f, -57.0f,
	-30.0f, -0.5f, -57.0f,
	0.0f,-0.5f,-40.0f,

	//back of bottom of tail
	30.0f,-0.5f,-57.0f,
	-30.0f, -0.5f, -57.0f,
	0.0f, 4.0f, -57.0f,

	//Top of Tail section left
	0.0f,0.5f,-40.0f,
	3.0f, 0.5f, -57.0f,
	0.0f, 25.0f, -65.0f,

	0.0f, 25.0f, -65.0f,
	-3.0f, 0.5f, -57.0f,
	0.0f,0.5f,-40.0f,

	//Back of horizontal section
	3.0f,0.5f,-57.0f,
	-3.0f, 0.5f, -57.0f,
	0.0f, 25.0f, -65.0f,
};
GLbyte colors[JET_FACE_SIZE * 3] = {
		// Nose Cone
		255, 255, 255,
		0,0,0,
		// Red
		255,0,0,
		// Body of the Plane
		// Green
		0,255,0,
		255,255,0,
		0, 255, 255,
		// Left wing
		// Large triangle for bottom of wing
		128,128,128,
		64,64,64,
		192,192,192,
		// Other wing top section
		64,64,64,
		// Tail section
		// Bottom of back fin
		255,128,255,
		// top of left side
		255,128,0,
		// top of right side
		255,128,0,
		// back of bottom of tail
		255,255,255,
		// Top of Tail section left
		255,0,0,
		255,0,0,
		// Back of horizontal section
		128,128,128,
};
static GLfloat normals[JET_FACE_SIZE * 3];
#include <gl_utils.h>
void calculateNormals(GLfloat normals[], GLfloat vertexes[], int faces){
	for(int i = 0; i < faces; i++){
		calculateNormal(normals + i * 3, vertexes + i * 9);
	}
}
void drawJet(){
	static GLboolean shouldInit = GL_TRUE;
	if(shouldInit){
		calculateNormals(normals, vertexes, JET_FACE_SIZE);
		shouldInit = GL_FALSE;
	}
    glBegin(GL_TRIANGLES);
    for(int i = 0; i < JET_FACE_SIZE; i++){
    	glNormal3fv(normals + i * 3);
    	glVertex3f(vertexes[i * 9 + 0], vertexes[i * 9 + 1], vertexes[i * 9 + 2]);
    	glVertex3f(vertexes[i * 9 + 3], vertexes[i * 9 + 4], vertexes[i * 9 + 5]);
    	glVertex3f(vertexes[i * 9 + 6], vertexes[i * 9 + 7], vertexes[i * 9 + 8]);
    }
    glEnd();
}
void drawSphere(GLfloat radius, GLint numX, GLint numY){
	GLfloat yStep = PI / numY;
	GLfloat xStep = 2 * PI / numX;
	GLfloat angleY0 = PI;
	GLfloat angleY1 = angleY0 - yStep;

	for(int i = 0; i < numY; i++){
		GLfloat angleX = 0;
		glBegin(GL_TRIANGLE_STRIP);
		for(int j = 0; j <= numX; j++){
			glNormal3f(sin(angleY0) * cos(angleX), cos(angleY0), sin(angleY0) * sin(angleX));
			glVertex3f(radius * sin(angleY0) * cos(angleX),
				radius * cos(angleY0),
				radius * sin(angleY0) * sin(angleX));
			glNormal3f(sin(angleY1) * cos(angleX), cos(angleY1), sin(angleY1) * sin(angleX));
			glVertex3f(radius * sin(angleY1) * cos(angleX),
				radius * cos(angleY1),
				radius * sin(angleY1) * sin(angleX));
			angleX += xStep;
		}
		glEnd();
		angleY0 = angleY1;
		angleY1 -= yStep;
	}
}
